﻿#ifndef XRTCCLIENT_BASE_XRTC_PUSHER_H_
#define XRTCCLIENT_BASE_XRTC_PUSHER_H_

#include <rtc_base/thread.h>
#include<mutex>

#include "xrtc/ixrtc_engine.h"
#include "xrtc/ixrtc_pusher.h"
#include "base/xrtc_http.h"
#include "stream/push_stream.h"
#include"websocket/ffwebsocketsignalclient.h"
#include"render/d3d9_render.h"

namespace xrtc {

class XRTCPusher : public IXRTCPusher,
                   public sigslot::has_slots<>,
                   public FFWebSocketSignalObserver
{
public:
    bool StartPush(const std::string& url,
        IXRTCVideoSource* video_source, const XRTCCanvas& canvas, std::string uid, std::string roomId) override;
    void StopPush() override;

    void DoOffer(std::string const offer);
    void DoAnswer(std::string const answer);
    void DoCandidate(const webrtc::IceCandidateInterface* candidate);
    void DoJoin(std::string const roomId, std::string const uid);
    void DoLeave();
    void DoRender(WebRTCStream* stream, rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver);


private:
    XRTCPusher();
    ~XRTCPusher() override;

    void OnAnswerReady(WebRTCStream* stream, const std::string& answer);
    void OnStreamState(WebRTCStream* stream, XRTCStreamState state);
    void StartRender(webrtc::VideoTrackInterface* video_track);

    bool ParseReply(const HttpReply& reply,
        std::string& type,
        std::string& sdp);
    bool ParseReply(const HttpReply& reply);
    void DoStreamStateChange(WebRTCStream* stream, XRTCStreamState state);
    void DoStopStream(xrtc::XRTCError err);

    //对端加入
    virtual void handleRemoteNewPeer(json const JMsg) override;

    //本地加入
    virtual void handleResponseJoin(json const JMsg) override;

    //对端离开
    virtual void handleRemotePeerLeave(json const JMsg) override;

    //收到offer
    virtual void handleRemoteOffer(json const JMsg) override;

    //收到answer
    virtual void handleRemoteAnswer(json const JMsg) override;

    //收到candidate
    virtual void handleRemoteCandidate(json const JMsg) override;


private:
    void SendStartPushEvent(XRTCError err);
    void SendStopPushEvent(XRTCError err);

    void Start(const std::string url);
    void Stop();
    int Send(std::string const message);

private:
    rtc::Thread* current_thread_;
    std::string url_;
    std::string protocol_;
    std::string host_;
    std::string action_;
    std::map<std::string, std::string> request_params_;
    std::unique_ptr<PushStream> push_stream_;

    IXRTCVideoSource* video_source_ = nullptr;
    friend class XRTCEngine;

    std::mutex mutex_;
    std::thread* websocket_thread_ = nullptr;
    std::atomic<bool> running_ = { false };

    std::unique_ptr<FFWebSocketSignalClient> websocket_client_ = nullptr;

    XRTCCanvas canvas_;
    std::unique_ptr<D3D9Render> render_;

    std::string uid_;
    std::string remoteUid_;
    std::string roomId_;
};

} // namespace xrtc

#endif // XRTCCLIENT_BASE_XRTC_PUSHER_H_